package com.jiankangjin.transsystem.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jiankangjin.httpclient.HttpClient;
import com.jiankangjin.trading.dao.IChannelDao;
import com.jiankangjin.trading.dao.IOrderDataDao;
import com.jiankangjin.trading.dao.IPaymentDataDao;
import com.jiankangjin.trading.entity.ChannelEntity;
import com.jiankangjin.trading.entity.OrderDataEntity;
import com.jiankangjin.trading.entity.PaymentDataEntity;
import com.jiankangjin.transsystem.common.CommonResponse;
import com.jiankangjin.transsystem.common.Constant;
import com.jiankangjin.transsystem.util.StringUtil;
import com.jiankangjin.transsystem.util.TimeUtil;
import com.jiankangjin.transsystem.vo.RefundOrderBean;

/**  
 * 用户申请退款后，商户进行退款复核。
 * 复核成功后，支付金额将返回给用户
 */
@Controller
public class AllowRefundController {
	
	private static final Log log = LogFactory.getLog(AllowRefundController.class);
	
	@Autowired
	private IOrderDataDao iOrderDataDao;
	
	@Autowired
	private IPaymentDataDao iPaymentDataDao;
	
	@Autowired
	private IChannelDao iChannelDao;

	/**
	 * 退款复核接口
	 */
	@RequestMapping(value="/allow_refund" , method=RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> allow_refund(
			@RequestParam(required = false) String module_id,
			@RequestParam(required = false) String version,
			@RequestParam(required = false) String order_id,
			@RequestParam(required = false) String refund_fee,
			@RequestParam(required = false) String comment,
			@RequestParam(required = false) String sign,
            @RequestParam(required = false) String operator_id,
            @RequestParam(required = false) String operator_name
			){
		StringBuilder sb = new StringBuilder();
		sb.append("module_id=" + module_id);
		sb.append(" version=" + version);
		sb.append(" order_id=" + order_id);
		sb.append(" refund_fee=" + refund_fee);
		sb.append(" comment=" + comment);
		sb.append(" sign=" + sign);
		sb.append(" operator_id=" + operator_id);
		sb.append(" operator_name=" + operator_name);
		if (log.isInfoEnabled()) {
			log.info("退款复核接口：" + sb);
		}
		
		// 1.验证有效性
		if (StringUtil.isEmpty(module_id)) {
			String errorMsg = Constant.RESP_STAT_MSG_0001+","+"请求模块编号为空";
			return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_0001,errorMsg);
		}
		if (StringUtil.isEmpty(version)) {
			String errorMsg = Constant.RESP_STAT_MSG_0001+","+"版本号为空";
			return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_0001,errorMsg);
		}
		if (StringUtil.isEmpty(order_id)) {
			String errorMsg = Constant.RESP_STAT_MSG_0001+","+"订单编号为空";
			return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_0001,errorMsg);
		}
		if (StringUtil.isEmpty(refund_fee)) {
			String errorMsg = Constant.RESP_STAT_MSG_0001+","+"退款金额为空";
			return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_0001,errorMsg);
		}
		if (StringUtil.isEmpty(sign)) {
			String errorMsg = Constant.RESP_STAT_MSG_0001+","+"签名为空";
			return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_0001,errorMsg);
		}
		
		// 2.不可退款复核的情况
		OrderDataEntity orderData = iOrderDataDao.selectByPrimaryKey(order_id);
		// 2.1 订单不存在，退款失败
		if (orderData == null) {
			String errorMsg = Constant.RESP_STAT_MSG_0002;
			return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_0002,errorMsg);
		}
		// 2.2 未申请退款，退款失败
		if (!Constant.ORD_REFUND_STAT_CODE_APPLIED.equals(orderData.getRefundStat())) {
			String errorMsg = Constant.RESP_STAT_MSG_0004;
			return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_0004,errorMsg);
		}
		// 2.3正在复核，退款失败
		if (Constant.ORD_REFUND_STAT_CODE_REFUNDING.equals(orderData.getRefundStat())) {
			String errorMsg = Constant.RESP_STAT_MSG_0015;
			return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_0015,errorMsg);
		}
		try {
			//订单支付记录 （已支付成功的)
			PaymentDataEntity entity = new PaymentDataEntity();
			entity.setOrdSysId(order_id);
			entity.setPayMthd(Constant.PAY_METHOD_0001);
			entity.setPayStat(Constant.PAY_STAT_CODE_SUCCESS);
			List<PaymentDataEntity> paymentList = iPaymentDataDao.listByEntity(entity);
			//去掉已经退款成功的记录
			List<PaymentDataEntity> paymentList1 = new ArrayList<>();
			for (PaymentDataEntity pay : paymentList) {
				if (!Constant.REFUND_STAT_CODE_SUCCESS.equals(pay.getRefundStat())) {
					paymentList1.add(pay);
				}
			}
			paymentList = paymentList1;
			if (paymentList == null || paymentList.size()<=0) {
				// 2.3.没有可退款的支付记录
				String errorMsg = Constant.RESP_STAT_MSG_0006;
				return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_0006,errorMsg);
			}
			// 3.开始退款
			// 3.1.订单预退款处理
			// 3.1.1.订单退款开始时间----改为申请退款的时间
			//orderData.setRefundStartTime(sdf.format(new Date()));//退款开始时间
			// 3.1.2.订单退款次数
			int orderRefundCnt = StringUtil.Str2int(orderData.getRefundCnt());
			orderData.setRefundStat(Constant.ORD_REFUND_STAT_CODE_REFUNDING);//正在退款复核
			orderData.setRefundCnt(orderRefundCnt+1+"");//加1次
			if (iOrderDataDao.update(orderData) > 0) {
				log.info("订单" + orderData.getId() + "预退款,已更新");
			}
			// 3.2.支付记录处理
			RefundOrderBean resultRefundOrderBean = new RefundOrderBean();
			for (PaymentDataEntity pay : paymentList) {
				// 3.2.1.本条支付记录 开始退款
				pay.setRefundStat(Constant.REFUND_STAT_CODE_PROCESSING);//正在退款
				int payRefundCnt = StringUtil.Str2int(pay.getRefundCnt());
				pay.setRefundCnt(payRefundCnt+1+"");//加1次
				if (iPaymentDataDao.update(pay) > 0) {
					log.info("\t支付记录" + pay.getId() + "预退款,已更新");
				}
				
				PaymentDataEntity refundPay = null;//支付记录对应的退款记录
				refundPay = iPaymentDataDao.selectByPrimaryKey(pay.getRefundSeq());
				
				// 3.2.2.本条支付记录根据支付的渠道路由，退款
				ChannelEntity channel = iChannelDao.selectByPrimaryKey(pay.getPayChnl());
				RefundOrderBean refundOrderBean = new RefundOrderBean();
				refundOrderBean.setRefund_fee(refund_fee);
				refundOrderBean.setPaymentData(pay);
				refundOrderBean.setOrderData(orderData);
				if (channel == null) {
					log.error("\t此支付记录的支付渠错误,无法退款");
					resultRefundOrderBean = refundOrderBean;
					resultRefundOrderBean.getPaymentData().setRefundStat(Constant.REFUND_STAT_CODE_FAIL);
				} else {
					resultRefundOrderBean = this.doRoute(channel, refundOrderBean);
				}
				
				// 3.2.3.本条支付记录退款结束，更新表
				if (iPaymentDataDao.update(resultRefundOrderBean.getPaymentData()) > 0) {
					log.info("\t此支付记录退款结束,已更新");
				}
				
				// 支付记录对应的退款记录更新
				refundPay.setRefundOperatorId(operator_id);
				refundPay.setRefundOperatorName(operator_name);
				refundPay.setRefundComment(comment);
				refundPay.setRefundTime(TimeUtil.getTime());
				refundPay.setRefundStat(resultRefundOrderBean.getPaymentData().getRefundStat());
				refundPay.setRefundAmt(resultRefundOrderBean.getPaymentData().getRefundAmt());
				iPaymentDataDao.update(refundPay);
			}
			// 3.3.订单退款结束，更新订单表
			int agoPayAmt = StringUtil.Str2int(orderData.getPayAmt());
			int agoRefund = 0; //本次退款后，已退款金额
			PaymentDataEntity example = new PaymentDataEntity();
			example.setOrdSysId(orderData.getId());
			example.setPayMthd(Constant.PAY_METHOD_0001);
			example.setRefundStat(Constant.REFUND_STAT_CODE_SUCCESS);
			List<PaymentDataEntity> listPaymentData = iPaymentDataDao.listByEntity(example);
			for (int i = 0; i < listPaymentData.size(); i++) {
				agoRefund += Integer.parseInt(listPaymentData.get(i).getRefundAmt());//历史退款成功记录金额累加 
			}
			int canRefund = agoPayAmt - agoRefund; //可退款金额
			log.info("已支付金额=" + agoPayAmt + " 历史已退款金额=" + agoRefund + " 当前可退款金额=" + canRefund);
			if (agoRefund != 0) {
				if(canRefund > 0) {//部分退款
					resultRefundOrderBean.getOrderData().setRefundStat(Constant.ORD_REFUND_STAT_CODE_PARTREFUND);
				} else {//全部退款
					resultRefundOrderBean.getOrderData().setRefundStat(Constant.ORD_REFUND_STAT_CODE_SUCCESS);
				}
			} else {
				resultRefundOrderBean.getOrderData().setRefundStat(Constant.ORD_REFUND_STAT_CODE_NOTREFUND);
			}
			resultRefundOrderBean.getOrderData().setRefundAmt(agoRefund+"");
			resultRefundOrderBean.getOrderData().setRefundEndTime(TimeUtil.getTime());
			if (iOrderDataDao.update(resultRefundOrderBean.getOrderData()) > 0) {
				log.info("退款结束,订单表已更新");
			}
			
			// 4.返回结果
			Map<String, Object> result = new HashMap<>();
			result.put(Constant.RESP_PARAM_STAT, Constant.RESP_STAT_CODE_0000);
			result.put(Constant.RESP_PARAM_MSG, Constant.RESP_STAT_MSG_0000);
			result.put(Constant.RESP_PARAM_SUBREFUNDSTATUS, resultRefundOrderBean.getOrderData().getRefundStat());
			result.put(Constant.RESP_PARAM_SIGN, "transsystem_allowrefund_sign");
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("退款过程中发生异常");
			String errorMsg = Constant.RESP_STAT_MSG_9999;
			return CommonResponse.formatErrorResult(Constant.RESP_STAT_CODE_9999,errorMsg);
		}
	}
	
	/**
	 * 渠道路由-退款
	 */
	private RefundOrderBean doRoute(ChannelEntity channel, RefundOrderBean refundOrderBean) {
		String path = "http://" + channel.getProjectUrl() + ":"
				+ channel.getProjectPort() + "/" + channel.getProjectName()
				+ "/refund";
		log.info("路由至渠道："+ path + " (" + channel.getChannelFeeType() + " " + channel.getMethodVersion() +")");
		PaymentDataEntity payEntity = refundOrderBean.getPaymentData();
		OrderDataEntity orderEntity = refundOrderBean.getOrderData();
		Map<String, Object> params = new HashMap<>();
		params.put("channel_fee_type", channel.getChannelFeeType());
		params.put("version", channel.getMethodVersion());
		params.put("pay_ssn_id", payEntity.getId());
		params.put("order_id", orderEntity.getId());
		params.put("total_fee", payEntity.getPayAmt());//渠道下订单时的总金额，为支付记录的支付总金额
		params.put("pay_chnl_seq", payEntity.getPayChnlSeq());
		params.put("refund_fee", refundOrderBean.getRefund_fee());//退款金额为请求金额，但渠道一般不支付自定金额退款
		params.put("currency", orderEntity.getOrdCry());
		params.put("sign", "transSystem_refund_doRoute_sign");
		log.info("调渠道退款：" + params);
		Map<String, Object> refundMap = HttpClient.getInstance().doPOSTgetHashMap(path, params);
		log.info("渠道退款返回：" + refundMap);
		if (refundMap == null) {
			payEntity.setRefundStat(Constant.REFUND_STAT_CODE_FAIL);
			refundOrderBean.setRefund_status(Constant.REFUND_STAT_CODE_FAIL);
			return refundOrderBean;
		}
		if (Constant.RESP_STAT_CODE_0000.equals(refundMap.get("resp_status"))) {
			if (Constant.REFUND_STAT_CODE_SUCCESS.equals((String)refundMap.get("refund_status"))) {
				int refundAmt = StringUtil.Str2int(payEntity.getRefundAmt());//记录中以退金额
				int refund_fee = StringUtil.Str2int(payEntity.getPayAmt());//本次退款金额,为支付记录的金额
				System.out.println("refundAmt=" + refundAmt + " refund_fee=" + refund_fee);
				payEntity.setRefundAmt(refundAmt + refund_fee + "");
				payEntity.setRefundStat(Constant.REFUND_STAT_CODE_SUCCESS);
				refundOrderBean.setRefund_status(Constant.REFUND_STAT_CODE_SUCCESS);
				return refundOrderBean;
			}
		}
		payEntity.setRefundStat(Constant.REFUND_STAT_CODE_FAIL);
		refundOrderBean.setRefund_status(Constant.REFUND_STAT_CODE_FAIL);
		return refundOrderBean;
	}
}